package cn.com.fssg.platform.base.handler.impl.gsl.zw;

import cn.com.fssg.platform.base.handler.InterfaceHandler;
import cn.com.fssg.platform.biz.BizUtil;
import cn.com.fssg.platform.biz.ExtendUtil;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Component;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import java.nio.charset.StandardCharsets;
import java.util.*;

import cn.hutool.crypto.SmUtil;
import org.springframework.transaction.annotation.Transactional;

/**
 * @Description: 工商联执委信息插入数据接口
 */
@Component
public class GslZwInsertCtl implements InterfaceHandler {

    private NamedParameterJdbcTemplate jdbcTemplate = BizUtil.cur().tenantMainJdbcTemplate();

//    @Autowired
//    private NamedParameterJdbcTemplate jdbcTemplate;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Object run(HttpServletRequest request, JSONObject jsonObject) throws Exception {
        String result = checkForm(jsonObject);
        if(result != null) {
            return result;
        }
        String gslZwQyId = StringUtils.isEmpty(jsonObject.getString("qy_id")) ? BizUtil.cur().getSnowflakeIdStr() : jsonObject.getString("qy_id");
        jsonObject.put("gslZwQyId", gslZwQyId);
        //更新届次执委人数
        String jcId = jsonObject.getString("jc_id");
        if(StringUtils.isEmpty(jcId)) {
            //验证是否为人员登录，如果是，则人员必须存在届次绑定,直接取人员最新届次即可
            String queryJcSql = "select * from gsl_jc order by create_date desc limit 1";
            List<Map<String, Object> > jcList = jdbcTemplate.queryForList(queryJcSql, new HashMap<>());
            jcId = (String)jcList.get(0).get("id");
            jsonObject.put("jc_id", jcId);
        }
        //保存工商联执委人员信息
        saveGslZwInfo(jsonObject);
        String sql = "select id from gsl_jc_zw_user where gsl_session = :jcId";
        Map<String, Object> param = new HashMap<>();
        param.put("jcId", jcId);
        List<Map<String, Object> > jcUserList = jdbcTemplate.queryForList(sql, param);
        if(!jcUserList.isEmpty()) {
            String updateSql = "UPDATE gsl_jc SET zw_count = :zwCount WHERE id = :jcId";
            param.put("zwCount", jcUserList.size());
            jdbcTemplate.update(updateSql, param);
        }
        return null;
    }

    /** 验证表单数据 */
    public String checkForm(JSONObject jsonObject) throws Exception {
        String jcId = jsonObject.getString("jc_id");
        String phone = jsonObject.getString("phone");
        if(StringUtils.isEmpty(phone)) {
            return "请填写手机号码";
        }

        String gslZwId = jsonObject.getString("id");
        if(StringUtils.isEmpty(gslZwId)) {
            gslZwId = BizUtil.cur().getSnowflakeIdStr();
            jsonObject.put("id", gslZwId);
        }
        String querySql = "select * from gsl_zw_info where id = :id";
        Map<String, Object> param = new HashMap<>();
        param.put("id", gslZwId);
        List<Map<String, Object>> list = jdbcTemplate.queryForList(querySql, param);
        if(list.isEmpty()){
            String encryptPhone = encrypt(phone, "userltokon");
            String querySql1 = "select * from wx_user where phone = :phone and gsl_session = :jcId and del_flag = '0'";
            Map<String, Object> param1 = new HashMap<>();
            param1.put("phone", encryptPhone);
            param1.put("jcId", jcId);
            List<Map<String, Object>> wxUserList = jdbcTemplate.queryForList(querySql1, param1);
            if(!wxUserList.isEmpty()) {
                return "手机号码已存在";
            }
        }
        return null;
    }

    /** 保存工商联执委个人/企业信息 */
    public int saveGslZwInfo(JSONObject jsonObject) throws Exception {
        String gslZwId = jsonObject.getString("id");
        if(StringUtils.isEmpty(gslZwId)) {
            gslZwId = BizUtil.cur().getSnowflakeIdStr();
            jsonObject.put("id", gslZwId);
        }
        String querySql = "select * from gsl_zw_info where id = :id";
        Map<String, Object> param = new HashMap<>();
        param.put("id", gslZwId);
        List<Map<String, Object>> list = jdbcTemplate.queryForList(querySql, param);
        if(!list.isEmpty()){
            //存在历史执委信息，获取历史执委信息中的执委信息
            return updateGslZwInfo(list.get(0), jsonObject);
        } else {
            //验证当前登录用户是否为执委
            String wxUserId = BizUtil.cur().curUserId();
            boolean isZw = BizUtil.cur().curUserRoleContain("002");
            if(!isZw) {
                //不是执委登录，证明是管理员登录，需要增加平台用户的新增，暂时写的是没有关联
                wxUserId = BizUtil.cur().getSnowflakeIdStr();
            }
            //不存在历史执委信息
            return insertGslZwInfo(jsonObject, wxUserId);
        }
    }

    /** 编辑工商联执委个人/企业信息 */
    public int updateGslZwInfo(Map<String, Object> oldZw, JSONObject jsonObject) throws Exception {
        String wxUserId = (String) oldZw.get("zw_id");
        //获取wx_user信息
        String queryWxUserSql = "select * from wx_user where id = :id";
        Map<String, Object> wxUserParam = new HashMap<>();
        wxUserParam.put("id", wxUserId);
        List<Map<String, Object>> wxUserLists = jdbcTemplate.queryForList(queryWxUserSql, wxUserParam);
        Map<String, Object> oldUser = wxUserLists.get(0);

        String phone = jsonObject.getString("phone");
        String encryptPhone = encrypt(phone, "userltokon");
        oldUser.put("phone", encryptPhone);
        oldUser.put("login_name", encryptPhone);
        if(!Objects.isNull(jsonObject.getString("name"))){
            String userName = jsonObject.getString("name");
            String encryptUserName = encrypt(userName, "usertokon");
            oldUser.put("username", encryptUserName);
        }
        oldUser.put("update_date", new Date());
        oldUser.put("update_by", BizUtil.cur().curUserId());
        updateDatabase(oldUser, "wx_user");

        jsonObject.put("update_date", new Date());
        jsonObject.put("update_by", BizUtil.cur().curUserId());

        //保存gsl_zw_info
        Map<String, Object> zwInfoParam = getGslZwInfo(jsonObject);

        updateDatabase(zwInfoParam, "gsl_zw_info");

        //保存gsl_zw_qy
        Map<String, Object> zwQyParam = getGslZwQy(jsonObject);
        return updateDatabase(zwQyParam, "gsl_zw_qy");

    }

    /** 新增工商联执委个人/企业信息 */
    public int insertGslZwInfo(JSONObject jsonObject, String wxUserId) throws Exception {
        String jcId = jsonObject.getString("jc_id");
        //保存wx_user表数据
        Map<String, Object> wxUser = new HashMap<>();
        wxUser.put("gsl_session", jcId);
        wxUser.put("id", wxUserId);
        wxUser.put("update_by", BizUtil.cur().curUserId());
        wxUser.put("create_by", BizUtil.cur().curUserId());
        wxUser.put("update_date", new Date());
        wxUser.put("create_date", new Date());
        wxUser.put("del_flag", "0");
        wxUser.put("role_scope", "1");
        wxUser.put("parent_role_scope", "1");
        wxUser.put("login_flag", "0");
        wxUser.put("type", "0");
        wxUser.put("job_state", "1");
        String loginName = jsonObject.getString("phone");
        String encryptLoginName = encrypt(loginName, "userltokon");
        wxUser.put("login_name", encryptLoginName);
        wxUser.put("phone", encryptLoginName);
        String userName = jsonObject.getString("name");
        String encryptUserName = encrypt(userName, "usertokon");
        wxUser.put("username", encryptUserName);
        String password = loginName + ":" + "123456";
        wxUser.put("password", SmUtil.sm3(password));//这里需要加密

        String wxQuerySql = "select * from wx_user where login_name = :loginName and gsl_session = :gslSession";
        Map<String, Object> wxUserParam = new HashMap<>();
        wxUserParam.put("loginName", encryptLoginName);
        wxUserParam.put("gslSession", jcId);
        List<Map<String, Object>> wxUserList = jdbcTemplate.queryForList(wxQuerySql, wxUserParam);
        //保存wx_user数据
        if(!wxUserList.isEmpty()) {
            wxUser.put("id", wxUserList.get(0).get("id"));
        }
        updateDatabase(wxUser, "wx_user");
        if(ExtendUtil.cur().checkOnlyUser(loginName)) {
            //保存平台用户
            JSONObject userJson = new JSONObject();
            userJson.put("id", wxUserId);
            userJson.put("loginname", loginName);
            userJson.put("realname", userName);
            userJson.put("password", SmUtil.sm3(password));
            userJson.put("status", 1);
            userJson.put("updateBy", BizUtil.cur().curUserId());
            userJson.put("createBy", BizUtil.cur().curUserId());
            userJson.put("updateTime", new Date());
            userJson.put("createTime", new Date());
            userJson.put("selectedroles", "1976856675140206593");//执委角色

            ExtendUtil.cur().addUser(userJson);
        }

        //获取届次信息
        String queryJcSql = "select * from gsl_jc where id = :id";
        Map<String, Object> jcParam = new HashMap<>();
        jcParam.put("id", jcId);
        List<Map<String, Object>> jcLists = jdbcTemplate.queryForList(queryJcSql, jcParam);
        if(jcLists.isEmpty()){
            throw new Exception("执委届次信息获取失败，请刷新重试");
        }
        Map<String, Object> gslJcZwParam = new HashMap<>();
        gslJcZwParam.put("jc_id", jcId);
        gslJcZwParam.put("zw_id", wxUserId);
        gslJcZwParam.put("id", BizUtil.cur().getSnowflakeIdStr());
        gslJcZwParam.put("update_by", BizUtil.cur().curUserId());
        gslJcZwParam.put("create_by", BizUtil.cur().curUserId());
        gslJcZwParam.put("update_date", new Date());
        gslJcZwParam.put("create_date", new Date());
        gslJcZwParam.put("del_flag", "0");
        //保存gsl_jc_zw表
        updateDatabase(gslJcZwParam, "gsl_jc_zw");

        //保存gsl_zw_info
        jsonObject.put("zw_id", wxUserId);
        Map<String, Object> zwInfoParam = getGslZwInfo(jsonObject);
        updateDatabase(zwInfoParam, "gsl_zw_info");

        //保存gsl_zw_qy
        Map<String, Object> zwQyParam = getGslZwQy(jsonObject);
        return updateDatabase(zwQyParam, "gsl_zw_qy");
    }

    /** 更新数据库数据 */
    public int updateDatabase(Map<String, Object> param, String tableName) {
        String id = param.get("id").toString();
        String querySql = "select * from " + tableName + " where id = :id";
        Map<String, Object> params = new HashMap<>();
        params.put("id", id);
        List<Map<String, Object>> oldList = jdbcTemplate.queryForList(querySql, params);
        if (oldList.isEmpty()) {
            List<String> fields = new ArrayList<>();
            List<String> placeholders = new ArrayList<>();
            param.forEach((k, v) -> {
                if (v != null) {
                    fields.add(k);
                    placeholders.add(":" + k);
                }
            });

            String sql = String.format("INSERT INTO %s (%s) VALUES (%s)",
                    tableName,
                    String.join(", ", fields),
                    String.join(", ", placeholders)
            );
            return jdbcTemplate.update(sql, param);
        } else {
            List<String> fields = new ArrayList<>();
            param.forEach((k, v) -> {
                if (v != null && !"id".equals(k)) {
                    fields.add(k + " = :" + k);
                }
            });

            String sql = String.format("UPDATE %s SET %s WHERE id = '%s'",
                    tableName,
                    String.join(", ", fields),
                    param.get("id")
            );
            return jdbcTemplate.update(sql, param);
        }

    }

    /** 获取执委个人信息所需保存的数据 */
    public Map<String, Object> getGslZwInfo(JSONObject jsonObject) {
        Map<String, Object> result = new HashMap<>();
        mainFieldList.forEach(key -> {
            if(!Objects.isNull(jsonObject.get(key))) {
                if("name".equals(key)) {
                    //姓名，需要加密存储
                    try {
                        String encName = encrypt((String) jsonObject.get(key), "nametokon");
                        result.put(key, encName);
                    } catch (Exception e) {
                        result.put(key, jsonObject.get(key));
                    }
                } else if("phone".equals(key)) {
                    //手机号码，需要加密存储
                    try {
                        String encName = encrypt((String) jsonObject.get(key), "ankon");
                        result.put(key, encName);
                    } catch (Exception e) {
                        result.put(key, jsonObject.get(key));
                    }
                } else {
                    result.put(key, jsonObject.get(key));
                }
            }
        });
        return result;
    }
    /** 获取执委企业信息所需保存的数据 */
    public Map<String, Object> getGslZwQy(JSONObject jsonObject) {
        Map<String, Object> result = new HashMap<>();
        enterpriseFieldList.forEach(key -> {
            if(!Objects.isNull(jsonObject.get(key))) {
                result.put(key, jsonObject.get(key));
            }
        });
        result.put("id", jsonObject.get("gslZwQyId"));
        return result;
    }

    public static final String ALGORITHM = "AES";

    // 密钥补全
    public static byte[] padKey(byte[] key, int length) {
        return Arrays.copyOf(key, length);
    }

    /**
     * 字节数组转HEX字符串（替代Base64）
     */
    public static String bytesToHex(byte[] bytes) {
        StringBuilder hex = new StringBuilder(bytes.length * 2);
        for (byte b : bytes) {
            hex.append(String.format("%02X", b));
        }
        return hex.toString();
    }

    /** 数据加密 */
    public static String encrypt(String input, String keys) throws Exception {
        // 1. 补全密钥为16字节（AES-128）
        byte[] keyBytes = padKey(keys.getBytes(StandardCharsets.UTF_8), 16);
        SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");

        // 2. 初始化加密器
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, key);

        // 3. 加密并转为HEX字符串
        byte[] encryptedBytes = cipher.doFinal(input.getBytes(StandardCharsets.UTF_8));
        return bytesToHex(encryptedBytes);
    }

    public static final List<String> mainFieldList = Arrays.asList(
            "id",
            "name",
            "company",
            "sex",
            "phone",
            "nation",
            "postal_address",
            "birthday",
            "name_of_agent",
            "nationality",
            "gent_account_number",
            "native_place",
            "position",
            "birthplace",
            "academic_degree",
            "education",
            "honekong_id",
            "id_card",
            "is_cadre",
            "gsl_post",
            "political_outlook",
            "people_congress_post",
            "cppcc_post",
            "gsl_post_chose",
            "social_position",
            "no_post",
            "model_worker",
            "may_day_medal",
            "red_flag_bearer",
            "may_4t_medal",
            "excellent_bbuilder",
            "glory_medal",
            "order_awards",
            "no_social_honor",
            "curriculum_vitae",
            "update_by",
            "update_date",
            "create_by",
            "create_date",
            "del_flag",
            "remarks",
            "scope",
            "card_id",
            "people_congress_post_country",
            "people_congress_post_province",
            "people_congress_post_city",
            "people_congress_post_county",
            "cppcc_post_country",
            "cppcc_post_province",
            "cppcc_post_city",
            "cppcc_post_county",
            "gsl_post_chose_country",
            "gsl_post_chose_province",
            "gsl_post_chose_city",
            "gsl_post_chose_county",
            "zw_id",
            "dl_card",
            "sxzzbx"
    );

    public static final List<String> enterpriseFieldList = Arrays.asList(
            "id",
            "name_enterprise",
            "legal_representative",
            "enterprise_scale",
            "credit_code",
            "qy_scale",
            "insurance_number",
            "industry_classification",
            "postal_address",
            "postcode",
            "main_business",
            "qyjy_registered_capital",
            "qyjy_asset_load_ratio",
            "qyjy_total_assets",
            "qyjy_business_income",
            "qyjy_net_assets",
            "qyjy_total_profit",
            "qyjy_tax_amount",
            "zg_count",
            "zg_labor_contract",
            "zg_collective_contract",
            "dzz_is_dzz",
            "dzz_date",
            "dzz_chose",
            "dzz_count",
            "labour_union",
            "tzz_date",
            "tzz",
            "gysy",
            "qy_characteristic",
            "qy_info",
            "update_by",
            "update_date",
            "create_by",
            "create_date",
            "del_flag",
            "remarks",
            "zw_id",
            "scope",
            "card_id",
            "five_year",
            "sj_dzz_name",
            "dzz_sj_name",
            "dzz_job",
            "yfzxsl_country",
            "yfzxsl_province",
            "yfzxsl_city",
            "jkjbjsl_country",
            "jkjbjsl_province",
            "jkjbjsl_city",
            "is_gxjsqy",
            "patent_number",
            "yffy",
            "zjfs",
            "dzzbzcy",
            "dzzlxrxm",
            "lxdh",
            "zjtxqy_country",
            "zjtxqy_province",
            "yxgjqy",
            "cylzqy",
            "zzydxgjqy",
            "cfwbqqy",
            "ssgs",
            "zgmywbqqy",
            "gdbqmyqy",
            "qsbqqy",
            "bdltqy",
            "gmysgyqy",
            "qyjylytd",
            "myqyrck"
    );
}